﻿@page "/account/login"

@using Microsoft.AspNetCore.Authentication
@using CleanArchitecture.Blazor.Domain.Identity
@using CleanArchitecture.Blazor.Application.Common.Interfaces.Identity
@using CleanArchitecture.Blazor.Application.Features.Identity.Notifications.SendFactorCode
@using System.ComponentModel.DataAnnotations
@using CleanArchitecture.Blazor.Server.UI.Pages.Identity.Register
@using CleanArchitecture.Blazor.Server.UI.Pages.Identity.Forgot
@inherits OwningComponentBase
@inject ILogger<Login> Logger
@inject IStringLocalizer<Login> L



<PageTitle>@_title</PageTitle>

<div class="d-flex flex-column gap-y-3">
    <div class="d-flex flex-column">
        <EditForm Model="Input" OnValidSubmit="OnSubmit" FormName="login">
            <DataAnnotationsValidator />
            <MudText Typo="Typo.h4" GutterBottom="true">@L["Sign In"]</MudText>
            <MudText>
                @L["Do not have an account?"] <MudLink Href="@Register.PageUrl" Target="_self">@L["Sign Up"]</MudLink>
            </MudText>
            <!--user name-->
            <MudTextField @bind-Value="Input.UserName"
                          Label="@L["User name"]"
                          Variant="Variant.Outlined"
                          For="@(() => Input.UserName)"
                          Required="true"
                          RequiredError="@L["User name is required"]"
                          Class="my-4" />
            <!--password-->
            <MudTextField @bind-Value="Input.Password"
                          Label="@L["Password"]"
                          Variant="Variant.Outlined"
                          For="@(() => Input.Password)"
                          InputType="@_passwordInputType"
                          Required="true"
                          RequiredError="@L["Password is required"]"
                          Class="my-4"
                          Adornment="Adornment.End"
                          AdornmentIcon="@_passwordIcon"
                          OnAdornmentClick="TogglePasswordVisibility" />


            <div Class="d-flex justify-space-between align-center mb-1">
                <MudCheckBox @bind-Value="Input.RememberMe"
                             For="@(() => Input.RememberMe)"
                             Color="Color.Primary">
                    @L["Remember me"]
                </MudCheckBox>
                <MudLink Href="@Forgot.PageUrl">@L["Forgot password?"]</MudLink>
            </div>

            <MudButton Variant="Variant.Filled"
                       Color="Color.Primary"
                       Size="Size.Large"
                       ButtonType="ButtonType.Submit"
                       FullWidth="true">
                <MudText>@L["Sign In"]</MudText>
            </MudButton>
        </EditForm>

    </div>
    <div class="d-flex flex-column">

        <ExternalLoginPicker />

    </div>
</div>

@code {
    private UserManager<ApplicationUser> _userManager = null!;
    private SignInManager<ApplicationUser> _signInManager = null!;

    public const string PageUrl = "/account/login";
    private string? errorMessage;
    [SupplyParameterFromQuery] private string? ReturnUrl { get; set; }
    private string _title = "Sign In";
    private AuthenticationScheme[] externalLogins = [];

    // Password visibility toggle
    private bool _passwordVisible = false;
    private InputType _passwordInputType = InputType.Password;
    private string _passwordIcon = Icons.Material.Filled.VisibilityOff;

    private InputModel Input { get; set; } = new()
    {
        UserName = "administrator",
        Password = "Password123!",
        RememberMe = true
    };

    private void TogglePasswordVisibility()
    {
        _passwordVisible = !_passwordVisible;
        _passwordInputType = _passwordVisible ? InputType.Text : InputType.Password;
        _passwordIcon = _passwordVisible ? Icons.Material.Filled.Visibility : Icons.Material.Filled.VisibilityOff;
    }

    protected override Task OnInitializedAsync()
    {
        _title = L["Sign In"];
        _userManager = ScopedServices.GetRequiredService<UserManager<ApplicationUser>>();
        _signInManager = ScopedServices.GetRequiredService<SignInManager<ApplicationUser>>();
        return Task.CompletedTask;
    }


    public async Task OnSubmit()
    {
        // Check if the user exists
        var user = await _userManager.FindByNameAsync(Input.UserName);
        if (user == null)
        {
            errorMessage = L["The specified user does not exist."];
            Snackbar.Add(errorMessage, Severity.Error);
            return;
        }
        else if (!user.IsActive)
        {
            errorMessage = L["Your account is inactive. Please contact support for assistance."];
            Snackbar.Add(errorMessage, Severity.Error);
            return;
        }
        var result = await _userManager.CheckPasswordAsync(user, Input.Password);
        if (result)
        {
            // Direct redirect to GET login endpoint
            var loginUrl = $"/pages/authentication/login?userName={Uri.EscapeDataString(Input.UserName)}&password={Uri.EscapeDataString(Input.Password)}&rememberMe={Input.RememberMe}";
            if (!string.IsNullOrEmpty(ReturnUrl))
            {
                loginUrl += $"&returnUrl={Uri.EscapeDataString(ReturnUrl)}";
            }

            Navigation.NavigateTo(loginUrl, forceLoad: true);
        }
        else
        {
            errorMessage = L["The username or password is incorrect. Please try again."];
            Snackbar.Add(errorMessage, Severity.Error);
        }
    }

    public sealed class InputModel
    {
        [Required(ErrorMessage = "User name is required")]
        [StringLength(100, ErrorMessage = "Name length can't be more than 100.")]
        public string UserName { get; set; } = "";

        [Required(ErrorMessage = "Password is required")]
        [StringLength(30, ErrorMessage = "Password must be at least 6 characters long.", MinimumLength = 6)]
        public string Password { get; set; } = "";

        public bool RememberMe { get; set; } = true;
    }

}